<template>
  <h4>当前求和为:{{ sum }}</h4>
  <button @click="sum++">点我++</button>
  <hr>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪资:{{ job.j1.salary }}K</h2>
  <div v-show="person.car">
    座驾名称:{{ person.car.name }}
    座驾价格:{{ person.car.price }}
  </div>
  <button @click="name += '~'">修改姓名</button>
  <button @click="age++">修改年龄</button>
  <button @click="job.j1.salary++">涨薪</button>
  <button @click="showRawPerson">输出最原始的person</button>
  <button @click="addCar">给人添加一台车</button>
  <button @click="person.car.name+='!'">换车名</button>
  <button @click="changePrice">换价格</button>
</template>

<script>
import { ref, reactive, toRefs, toRaw, markRaw } from "vue"; // toRaw 用的不多
export default {
  name: "demo",
  setup() {
    let sum = ref(0)

    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      },
      car: '',
      // axios: '' 用markRaw标记,不可变
    })

    // toRaw 只能处理reactive缔造的响应式对象,不能处理ref类型的数据
    
    /**
     * toRaw: 
     * 作用: 将一个由reactive生成的响应式对象转为普通对象
     * 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新
     */
    function showRawPerson() {
      console.log(person) // Proxy {name: "张三", age: 18, job: {…}}
      const p = toRaw(person)
      console.log(p) // {name: "张三", age: 18, job: {…}}
      p.name = '李四'
      console.log('p.name==', p.name) // 李四
    }

    
    /**
     * markRaw
     * 作用:标记一个对象,使其永远不会再成为响应式对象
     * 应用场景:
     *      1.有些值不应被设置为响应式的,例如复杂的第三方类库等
     *      2.当渲染具有不可变数据源的大列表时,跳过响应式转换可以提供性能
     */
    function addCar() {
      let car = { name: '奔驰', price: 40 }

      // 如果直接这样写,person里的name和price是可以修改的
      // person.car = car

      // 如果加了markRaw的话,person里的card的的name和price是改不了的
      // 也就是说,点击换名车和换价格连个方法，没效果
      person.car = markRaw(car)
      person.car.name = '宝马'
      console.log(person)
    }
 
    function changePrice() {
      person.car.price++
      console.log(person.car.price) // price会递增，页面显示的价格是40不会变化
    }

    return {
      sum,
      person,
      ...toRefs(person),
      showRawPerson,
      addCar,
      changePrice
    };
  },
};
</script>


